#include "threadPool.h"
/* Usage: 发送文件 */
int delimPath(char *abPath,char **pfilename){
    char delim[2] = "/";
    *pfilename = abPath;
    printf("%s\n",*pfilename);
    char *token = strtok(abPath,delim);
    while(token != NULL){
        *pfilename = token;
        printf("%s\n",*pfilename);
        token = strtok(NULL,delim);
        if(token == NULL){
            break;
        }
    }
    printf("%s\n",*pfilename);
    return 0;
}

int recvn(int netfd,void *buf,ssize_t length){// 解决半包问题
    char *p = (char *)buf;
    ssize_t cursize = 0;
    while(cursize < length){
        ssize_t sret = recv(netfd,p + cursize,length - cursize,0);
        cursize += sret;
    }
    return 0;
}

int getsFile(int netfd,const char *abPath){
    train_t train;
    train.cmd = -1;// 没用
    off_t cursize;
    char path[1024];
    bzero(path,sizeof(path));
    char buf[1024];// 
    bzero(buf,sizeof(buf));
    strcpy(path,abPath);
    printf("file:%s\n",path);

    int fd = open(path,O_RDWR);//绝对路径打开文件
    printf("fd:%d\n",fd);
    struct stat statbuf;
    fstat(fd,&statbuf);
    printf("before get cursize!\n");
    recvn(netfd,&cursize,sizeof(cursize));
    printf("after get cursize,cursize = %ld!\n",cursize);
    printf("filesize = %ld\n",statbuf.st_size - cursize);
    off_t filesize = statbuf.st_size - cursize;// 文件大小
    train.length = sizeof(filesize);
    memcpy(train.data,&filesize,sizeof(off_t));
    printf("%d,%d,%ld\n",train.cmd,train.length,filesize);
    send(netfd,&train,sizeof(train.cmd)+sizeof(train.length)+train.length,MSG_NOSIGNAL);
    printf("after send size.\n");
    // 开始传输
    if(filesize > 100000000){
        ftruncate(fd,filesize);
        char *p =(char *)mmap(NULL,filesize,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
        send(netfd,p+cursize,filesize,MSG_NOSIGNAL);
        munmap(p,filesize);
    }else{
        off_t curSize = cursize;
        sendfile(netfd,fd,&curSize,filesize);// 从cursize继续传输
    }
    // 传输完成 向客户端发送完成信息
    char *filename = NULL;
    delimPath(path,&filename);
    sprintf(buf,"%s is downloaded!",filename);
    send(netfd,buf,strlen(buf),0);
    close(fd);
    return 0;
}

/*Usage: 接收文件*/

int putsFile(int netfd,const char *abPath){
    printf("join putsFile!\n");
    train_t train;
    struct stat statbuf;
    int fd;
    off_t cursize = 0;
    off_t filesize;
    char path[1024];
    bzero(path,sizeof(path));
    char buf[1024];
    bzero(buf,sizeof(buf));
    strcpy(path,abPath);
    int ret = access(path,F_OK);// 判断文件是否存在
    if(ret == 0){
        printf("Reupload!\n");
        fd = open(path,O_RDWR);
        fstat(fd,&statbuf);
        cursize = statbuf.st_size;
    }else if(ret == -1){
        fd = open(path,O_RDWR|O_CREAT|O_TRUNC,0666);
    }else{
        return -1;
    }
    printf("before send\n");
    train.cmd = -1;
    train.length = sizeof(cursize);
    memcpy(train.data,&cursize,train.length);
    send(netfd,&train,sizeof(train.cmd)+sizeof(train.length)+train.length,MSG_NOSIGNAL);// 告诉客户端已经传了多少
    printf("after send\n");
    recvn(netfd,&train.cmd,sizeof(train.cmd));
    printf("cmd: %d",train.cmd);
    recvn(netfd,&train.length,sizeof(train.length));
    recvn(netfd,train.data,train.length);
    memcpy(&filesize,train.data,train.length);
    printf("filesize = %ld\n",filesize);

    ftruncate(fd,cursize+filesize);
    char *p = (char *)mmap(NULL,cursize+filesize,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
    recvn(netfd,p+cursize,filesize);
    char *filename = NULL;
    delimPath(path,&filename);
    sprintf(buf,"%s is uploaded!",filename);
    send(netfd,buf,strlen(buf),0);
    close(fd);
    return 0;
}

int removeFile(int netfd,const char *abPath){
    char path[1024];
    bzero(path,sizeof(path));
    char buf[1024];
    bzero(buf,sizeof(buf));
    strcpy(path,abPath);
    int ret = access(path,F_OK);
    if(ret == -1){
        send(netfd,"remove failed,the document does not exist.",42,0);
        return -1;
    }
    remove(path);
    char *filename = NULL;
    delimPath(path,&filename);
    sprintf(buf,"%s is deleted!",filename);
    send(netfd,buf,strlen(buf),0);
    return 0;
}
